package com.fubowen.reader.ui.fragment

import android.view.Gravity
import android.view.View
import android.widget.HorizontalScrollView
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.widget.PopupMenu
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.size
import androidx.core.widget.ContentLoadingProgressBar
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.fubowen.reader.R
import com.fubowen.reader.adapter.TreeAdapter
import com.fubowen.reader.extension.setVisible
import com.fubowen.reader.db.model.OptionsMenuItem
import com.fubowen.reader.db.model.Tree
import kotlinx.coroutines.launch

abstract class TreeFragment : ThemeFragment() {

    open val isEnableOnBack = false
    lateinit var onBackCallback: OnBackPressedCallback

    lateinit var tree: ConstraintLayout
    lateinit var recycler: RecyclerView
    lateinit var recyclerLoading: ContentLoadingProgressBar
    lateinit var recyclerLoadingHint: TextView
    lateinit var adapter: TreeAdapter
    lateinit var layoutManager: LinearLayoutManager

    open val isEnableTree = true
    open val button = ""
    open var selector = lazy { TreeSelectedFragment() }


    //region 面包屑导航

    lateinit var breadcrumb: HorizontalScrollView
    lateinit var breadcrumbList: LinearLayout
    val breadcrumbItems = mutableListOf<Tree>()
    open val isEnableBreadcrumb = true
    open fun onBreadcrumbClick(item: Tree) {}
    open fun setBreadcrumb(item: Tree) {
        val index = breadcrumbItems.indexOf(item)
        if (index != -1) {
            val removeList = breadcrumbItems.filterIndexed { i, _ -> i > index }
            breadcrumbItems.removeAll(removeList)
            breadcrumbList.removeViews(index + 1, removeList.size)
            val current = breadcrumbList.getChildAt(index)
            if (current is TextView) {
                current.text = item.name
            }
        } else {
            if (breadcrumbItems.isNotEmpty()) {
                val current = breadcrumbList.getChildAt(breadcrumbItems.size - 1)
                if (current is TextView) {
                    current.text = getString(R.string.breadcrumbItem, breadcrumbItems.last().name)
                }
            }
            TextView(requireContext()).apply {
                text = item.name
                setTextAppearance(R.style.TabLayout)
                setOnClickListener { onBreadcrumbClick(item) }
                breadcrumbList.addView(this)
                breadcrumbItems.add(item)
            }
        }
    }

    //endregion

    //region 右上角扩展菜单

    lateinit var optionsMenuAnchor: ImageView
    open var isEnableOptionsMenu = false
    open var optionsMenuList = mutableListOf<OptionsMenuItem>()
    open var optionsMenu = lazy {
        PopupMenu(requireContext(), optionsMenuAnchor).apply {
            optionsMenuList.forEach { menu.add(it.group, it.id, it.order, it.title) }
            gravity = Gravity.RIGHT or Gravity.BOTTOM
            setOnMenuItemClickListener { menuItem ->
                val item = optionsMenuList.find { it.isSame(menuItem) }
                item?.onClick?.invoke()
                item != null
            }
        }
    }

    open fun showOptionsMenu() = optionsMenu.value.show()

    //endregion

    //region initRecyclerView
    fun initRecyclerView(view: View) {
        setOnBack()
        tree = view.findViewById(R.id.tree)
        recycler = view.findViewById(R.id.tree_recycler)
        recyclerLoading = view.findViewById(R.id.tree_recycler_loading)
        recyclerLoadingHint = view.findViewById(R.id.tree_recycler_loading_hint)
        breadcrumb = view.findViewById(R.id.tree_breadcrumb)
        breadcrumbList = view.findViewById(R.id.tree_breadcrumb_list)
        optionsMenuAnchor = view.findViewById(R.id.tree_options_menu_anchor)
        layoutManager = recycler.layoutManager as LinearLayoutManager
        adapter = TreeAdapter(requireContext(), themeViewModel, button)
        recycler.layoutManager = layoutManager
        recycler.adapter = adapter
        recycler.itemAnimator = DefaultItemAnimator().apply { supportsChangeAnimations = false }
        adapter.setOnClickListener(OnItemClickListener())
        breadcrumb.setVisible(isEnableBreadcrumb)
        tree.setVisible(isEnableTree)
        optionsMenuAnchor.setOnClickListener { showOptionsMenu() }
        optionsMenuAnchor.setVisible(isEnableOptionsMenu)
        observerSize()
    }
    //endregion

    abstract fun onItemClick(view: View, item: Tree, position: Int)
    abstract fun onItemButtonClick(view: View, item: Tree, position: Int)
    abstract fun onSizeChanged(size: Int)

    //region showLoading，hideLoading
    fun showLoading(text: String) {
        recyclerLoading.show()
        recyclerLoadingHint.text = text
        recyclerLoadingHint.setVisible(true)
    }

    fun hideLoading() {
        recyclerLoading.hide()
        recyclerLoadingHint.setVisible(false)
    }
    //endregion

    //region 返回监听
    open fun setOnBack() {
        onBackCallback = object : OnBackPressedCallback(isEnableOnBack) {
            override fun handleOnBackPressed() {
                onBackCallback.isEnabled = onBack()
            }
        }
        requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, onBackCallback)
    }

    open fun onBack(): Boolean {
        if (isEnableBreadcrumb && breadcrumbItems.isNotEmpty()) {
            breadcrumbItems.removeLast()
            breadcrumbList.removeViewAt(breadcrumbList.size - 1)
            if (breadcrumbItems.isNotEmpty()) {
                val item = breadcrumbItems.last()
                setBreadcrumb(item)
                onBreadcrumbClick(item)
            }
            return breadcrumbItems.isNotEmpty()
        }
        return false
    }
    //endregion

    //region OnItemClickListener
    inner class OnItemClickListener : TreeAdapter.OnClickListener {
        override fun onItemClick(view: View) {
            val position = layoutManager.getPosition(view)
            val item = adapter.currentList[position]
            onItemClick(view, item, position)
        }

        override fun onSelectedClick(view: View) {
            val position = layoutManager.getPosition(view)
            val item = adapter.currentList[position]
            onItemButtonClick(view, item, position)
        }
    }
    //endregion

    private fun observerSize() {
        lifecycleScope.launch {
            cacheViewModel.sizeFlow.collect { size ->
                onSizeChanged(size)
            }
        }
    }

}